/**
 * @file VertexBufferImpl.h
 */
#ifndef INCLUDED_NTENGINE_GRAPHICS_INDEXBUFFERIMPL_H
#define INCLUDED_NTENGINE_GRAPHICS_INDEXBUFFERIMPL_H

#include "NTEngine/Graphics/IndexBuffer.h"
#include "NTEngine/Base/ReferenceType.h"

namespace NTEngine {
namespace Graphics {

class IndexBuffer::Impl : public ReferenceType {
public:
	Impl( IDirect3DDevice9* device, int indexNumber, Format fmt )
	: m_Object( NULL )
	, m_IndexNumber( indexNumber )
	, m_Format( fmt )
	{
		createObject( device );
	}
	~Impl() {
		SAFE_RELEASE( m_Object );
	}

	void* lock() {
		void* ret;
		m_Object->Lock( 0, 0, &ret, 0 );
		return ret;
	}

	void unlock() {
		m_Object->Unlock();
	}

	int indexNumber() const {
		return m_IndexNumber;
	}

	IDirect3DIndexBuffer9* object() {
		return m_Object;
	}

	Format format() {
		return m_Format;
	}

private:
	void createObject( IDirect3DDevice9* device ) {
		int size = m_IndexNumber;
		D3DFORMAT fmt;
		switch ( m_Format ) {
		case FMT_INDEX16:
			size *= sizeof( WORD );
			fmt = D3DFMT_INDEX16;
			break;
		case FMT_INDEX32:
			size *= sizeof( DWORD );
			fmt = D3DFMT_INDEX32;
			break;
		}
		HRESULT hr = device->CreateIndexBuffer( 
			size, 
			0,
			fmt, 
			D3DPOOL_MANAGED, 
			&m_Object, 
			NULL );
		ASSERT( hr != D3DERR_INVALIDCALL && "CreateVertexBuffer : INVALID CALL" );
		ASSERT( hr != D3DERR_OUTOFVIDEOMEMORY && "CreateVertexBuffer : OUT OF VIDEO MEMORY" );
		ASSERT( hr != E_OUTOFMEMORY && "CreateVertexBuffer : E OUT OF MEMORY" );
		ASSERT( SUCCEEDED( hr ) && "CreateVertexBuffer : error" );
	}
	IDirect3DIndexBuffer9* m_Object;
	int m_IndexNumber;
	Format m_Format;

	void operator=( const Impl& );
};

} // namespace Graphics
} // namespace NTEngine

#endif // INCLUDED_NTENGINE_GRAPHICS_INDEXBUFFERIMPL_H
// EOF